package com.carbeauty.entity;

import com.carbeauty.common.entity.BaseEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import java.math.BigDecimal;

/**
 * 订单详情实体类
 * 
 * 订单详情管理功能:
 * - 订单服务项目明细
 * - 数量和价格管理
 * - 折扣信息
 * - 服务人员记录
 * 
 * @author CarBeauty Team
 */
@Entity
@Table(name = "cb_order_detail")
public class OrderDetail extends BaseEntity {
    
    /**
     * 订单ID - 不使用外键约束
     */
    @NotNull(message = "订单ID不能为空")
    @Column(name = "order_id", nullable = false)
    private Long orderId;
    
    /**
     * 服务项目ID - 不使用外键约束
     */
    @NotNull(message = "服务项目ID不能为空")
    @Column(name = "service_id", nullable = false)
    private Long serviceId;
    
    /**
     * 服务项目名称 - 冗余字段，便于查询和历史记录
     */
    @NotNull(message = "服务项目名称不能为空")
    @Size(max = 100, message = "服务项目名称长度不能超过100个字符")
    @Column(name = "service_name", nullable = false, length = 100)
    private String serviceName;
    
    /**
     * 服务项目分类 - 冗余字段
     */
    @Size(max = 50, message = "服务分类长度不能超过50个字符")
    @Column(name = "service_category", length = 50)
    private String serviceCategory;
    
    /**
     * 服务数量
     */
    @NotNull(message = "服务数量不能为空")
    @DecimalMin(value = "0.01", message = "服务数量必须大于0")
    @Column(name = "quantity", nullable = false, precision = 10, scale = 2)
    private BigDecimal quantity = BigDecimal.ONE;
    
    /**
     * 单价
     */
    @NotNull(message = "单价不能为空")
    @DecimalMin(value = "0", message = "单价不能为负数")
    @Column(name = "unit_price", nullable = false, precision = 10, scale = 2)
    private BigDecimal unitPrice = BigDecimal.ZERO;
    
    /**
     * 原价小计
     */
    @NotNull(message = "原价小计不能为空")
    @DecimalMin(value = "0", message = "原价小计不能为负数")
    @Column(name = "original_amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal originalAmount = BigDecimal.ZERO;
    
    /**
     * 折扣率
     */
    @DecimalMin(value = "0", message = "折扣率不能为负数")
    @Column(name = "discount_rate", precision = 5, scale = 4)
    private BigDecimal discountRate = BigDecimal.ONE;
    
    /**
     * 折扣金额
     */
    @DecimalMin(value = "0", message = "折扣金额不能为负数")
    @Column(name = "discount_amount", precision = 10, scale = 2)
    private BigDecimal discountAmount = BigDecimal.ZERO;
    
    /**
     * 实际金额
     */
    @NotNull(message = "实际金额不能为空")
    @DecimalMin(value = "0", message = "实际金额不能为负数")
    @Column(name = "actual_amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal actualAmount = BigDecimal.ZERO;
    
    /**
     * 服务人员ID - 不使用外键约束
     */
    @Column(name = "employee_id")
    private Long employeeId;
    
    /**
     * 服务人员姓名 - 冗余字段
     */
    @Size(max = 50, message = "服务人员姓名长度不能超过50个字符")
    @Column(name = "employee_name", length = 50)
    private String employeeName;
    
    /**
     * 服务时长(分钟)
     */
    @Column(name = "service_duration")
    private Integer serviceDuration;
    
    /**
     * 详情备注
     */
    @Size(max = 200, message = "详情备注长度不能超过200个字符")
    @Column(name = "detail_remark", length = 200)
    private String detailRemark;
    
    // ==================== 构造方法 ====================
    
    public OrderDetail() {
        super();
    }
    
    public OrderDetail(Long orderId, Long serviceId, String serviceName, 
                      BigDecimal quantity, BigDecimal unitPrice) {
        super();
        this.orderId = orderId;
        this.serviceId = serviceId;
        this.serviceName = serviceName;
        this.quantity = quantity;
        this.unitPrice = unitPrice;
        this.calculateAmounts();
    }
    
    // ==================== Getter/Setter ====================
    
    public Long getOrderId() {
        return orderId;
    }
    
    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }
    
    public Long getServiceId() {
        return serviceId;
    }
    
    public void setServiceId(Long serviceId) {
        this.serviceId = serviceId;
    }
    
    public String getServiceName() {
        return serviceName;
    }
    
    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }
    
    public String getServiceCategory() {
        return serviceCategory;
    }
    
    public void setServiceCategory(String serviceCategory) {
        this.serviceCategory = serviceCategory;
    }
    
    public BigDecimal getQuantity() {
        return quantity;
    }
    
    public void setQuantity(BigDecimal quantity) {
        this.quantity = quantity;
        this.calculateAmounts();
    }
    
    public BigDecimal getUnitPrice() {
        return unitPrice;
    }
    
    public void setUnitPrice(BigDecimal unitPrice) {
        this.unitPrice = unitPrice;
        this.calculateAmounts();
    }
    
    public BigDecimal getOriginalAmount() {
        return originalAmount;
    }
    
    public void setOriginalAmount(BigDecimal originalAmount) {
        this.originalAmount = originalAmount;
    }
    
    public BigDecimal getDiscountRate() {
        return discountRate;
    }
    
    public void setDiscountRate(BigDecimal discountRate) {
        this.discountRate = discountRate;
        this.calculateAmounts();
    }
    
    public BigDecimal getDiscountAmount() {
        return discountAmount;
    }
    
    public void setDiscountAmount(BigDecimal discountAmount) {
        this.discountAmount = discountAmount;
    }
    
    public BigDecimal getActualAmount() {
        return actualAmount;
    }
    
    public void setActualAmount(BigDecimal actualAmount) {
        this.actualAmount = actualAmount;
    }
    
    public Long getEmployeeId() {
        return employeeId;
    }
    
    public void setEmployeeId(Long employeeId) {
        this.employeeId = employeeId;
    }
    
    public String getEmployeeName() {
        return employeeName;
    }
    
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    
    public Integer getServiceDuration() {
        return serviceDuration;
    }
    
    public void setServiceDuration(Integer serviceDuration) {
        this.serviceDuration = serviceDuration;
    }
    
    public String getDetailRemark() {
        return detailRemark;
    }
    
    public void setDetailRemark(String detailRemark) {
        this.detailRemark = detailRemark;
    }
    
    // ==================== 业务方法 ====================
    
    /**
     * 计算金额
     */
    public void calculateAmounts() {
        if (quantity != null && unitPrice != null) {
            // 计算原价小计
            this.originalAmount = quantity.multiply(unitPrice);
            
            // 计算折扣金额
            if (discountRate != null && discountRate.compareTo(BigDecimal.ONE) < 0) {
                this.discountAmount = originalAmount.multiply(BigDecimal.ONE.subtract(discountRate));
            } else {
                this.discountAmount = BigDecimal.ZERO;
            }
            
            // 计算实际金额
            this.actualAmount = originalAmount.subtract(discountAmount);
        }
    }
    
    /**
     * 应用折扣
     */
    public void applyDiscount(BigDecimal discountRate) {
        this.discountRate = discountRate;
        this.calculateAmounts();
    }
    
    /**
     * 应用固定折扣金额
     */
    public void applyFixedDiscount(BigDecimal discountAmount) {
        this.discountAmount = discountAmount;
        this.actualAmount = originalAmount.subtract(discountAmount);
        
        // 计算折扣率
        if (originalAmount.compareTo(BigDecimal.ZERO) > 0) {
            this.discountRate = actualAmount.divide(originalAmount, 4, BigDecimal.ROUND_HALF_UP);
        }
    }
    
    /**
     * 获取折扣百分比
     */
    public BigDecimal getDiscountPercentage() {
        if (discountRate != null) {
            return BigDecimal.ONE.subtract(discountRate).multiply(new BigDecimal("100"));
        }
        return BigDecimal.ZERO;
    }
    
    /**
     * 检查是否有折扣
     */
    public boolean hasDiscount() {
        return discountAmount != null && discountAmount.compareTo(BigDecimal.ZERO) > 0;
    }
}
